package org.template.dao;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Repository;
import org.template.dao.iter.RedisDelegator;
import org.template.dao.iter.RedisDelegatorNoResult;

import com.google.common.collect.Lists;

import redis.clients.jedis.Jedis;

@Repository
public class SortedSetRedisDao extends BaseRedisDao {

	public void add(final String key, final Double score, final String member) {

		runNoResult(new RedisDelegatorNoResult() {
			@Override
			public void execute(Jedis redis) {
				redis.zadd(key, score, member);
			}
		});

	}

	public void batchAdd(final String key, final Map<String, Double> members) {

		runNoResult(new RedisDelegatorNoResult() {
			@Override
			public void execute(Jedis redis) {
				redis.zadd(key, members);
			}
		});

	}

	public long rank(final String key, final String member) {

		return run(new RedisDelegator<Long>() {
			@Override
			public Long execute(Jedis redis) {
				return redis.zrank(key, member);
			}
		});

	}

	public void incrMemberScore(final String key, final String member, final double score) {

		runNoResult(new RedisDelegatorNoResult() {
			@Override
			public void execute(Jedis redis) {
				redis.zincrby(key, score, member);
			}
		});

	}

	public long revRank(final String key, final String member) {

		return run(new RedisDelegator<Long>() {
			@Override
			public Long execute(Jedis redis) {
				return redis.zrevrank(key, member);
			}
		});

	}

	public double getScore(final String key, final String member) {

		return run(new RedisDelegator<Double>() {
			@Override
			public Double execute(Jedis redis) {
				return redis.zscore(key, member);
			}
		});

	}

	public void removeMember(final String key, final String... members) {

		runNoResult(new RedisDelegatorNoResult() {
			@Override
			public void execute(Jedis redis) {
				redis.zrem(key, members);
			}
		});

	}

	public List<String> rangeByScore(final String key, final int min, final int max) {

		return run(new RedisDelegator<List<String>>() {
			@Override
			public List<String> execute(Jedis redis) {
				return setToArray(redis.zrangeByScore(key, min, max));
			}
		});

	}

	public List<String> revRangeMember(final String key, final int start, final int end) {

		return run(new RedisDelegator<List<String>>() {
			@Override
			public List<String> execute(Jedis redis) {
				return setToArray(redis.zrevrange(key, start, end));
			}
		});
	}

	public List<String> rangeMember(final String key, final int start, final int end) {

		return run(new RedisDelegator<List<String>>() {
			@Override
			public List<String> execute(Jedis redis) {
				return setToArray(redis.zrange(key, start, end));
			}
		});

	}

	public long getSize(final String key) {

		return run(new RedisDelegator<Long>() {
			@Override
			public Long execute(Jedis redis) {
				return redis.zcard(key);
			}
		});
	}
	
	private   List<String> setToArray(Set<String> members){
		if (null==members){
			return null;
		}
		return Lists.newArrayList(members);
	}
}
